import datetime
import json
from django import http
from django.shortcuts import render
from django.views import View
from django.core.paginator import Paginator, EmptyPage

from aijia_house.settings.dev import logger
from django.conf import settings
from fdfs_client.client import Fdfs_client
from aijia_house.utils.views import LoginRequiredJSONMixin
from apps.house.models import House, Facility, HouseImage
from apps.house.utils import house_to_dict
from apps.order.models import Order


# class DetailView(LoginRequiredJSONMixin, View):
class DetailView(View):
    """房源详情页"""

    def get(self, request, house_id):

        try:
            # 查询房子
            house = House.objects.get(id=house_id)
        except Exception as e:
            return http.JsonResponse({'errno': 4001, 'errmsg': '查询失败'})
        # 调用utils中查询房屋信息的函数
        house_dict = house_to_dict(house)

        # 返回数据
        return http.JsonResponse(
            {'errno': 0, 'errmsg': 'ok', 'data': {'user_id': request.user.id, 'house': house_dict}})


class HouseImageView(View):
    def post(self, request, house_id):

        # 接收参数  房源图片
        content = request.FILES.get('house_image')
        # content = request.POST.get('house_image').encode()
        print(content)

        # 判断是否为空
        if content is None:
            return http.JsonResponse({'errno': 4103, 'errmsg': '参数不能为空'})
        # 查询房屋是否存在
        try:
            house = House.objects.get(id=house_id)
        except Exception as e:
            return http.JsonResponse({'errno': 4001, 'errmsg': '房屋不存在'})
        # 上传到fdfs
        try:
            client = Fdfs_client(settings.FDFS_CLIENT_CONF)
            result = client.upload_by_buffer(content.read())

        except Exception as e:
            print(e)
            return http.JsonResponse({'errno': 4301, 'errmsg': '上传失败'})

        # 初始化房屋的图片模型
        file_id = result.get('Remote file_id')
        # 拼接图片访问地址
        url = settings.FDFS_BASE_URL + file_id
        try:
            house_image = HouseImage.objects.create(house=house, url=url)
        except Exception as e:
            return http.JsonResponse({'errno': 4001, 'errmsg': '保存失败'})

        # 判断是否有首页图片
        if not house.index_image_url:
            house.index_image_url = url
            house.save()

        return http.JsonResponse({'errno': 0, 'errmsg': 'ok'})


# 发布新房源
class IssueHouseView(LoginRequiredJSONMixin, View):

    def post(self, request):

        # 接收参数
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        price = json_dict.get('price')
        area_id = json_dict.get('area_id')
        address = json_dict.get('address')
        room_count = json_dict.get('room_count')
        acreage = json_dict.get('acreage')
        unit = json_dict.get('unit')
        capacity = json_dict.get('capacity')
        beds = json_dict.get('beds')
        deposit = json_dict.get('deposit')
        min_days = json_dict.get('min_days')
        max_days = json_dict.get('max_days')
        facilities = json_dict.get('facility')
        # 校验参数
        if not all([title, price, area_id, address, room_count, acreage, unit, capacity,
                    beds, deposit, min_days, max_days, facilities]):
            return http.JsonResponse({'errno': 4103, 'errmsg': '缺少参数'})
        if not int(price):
            return http.JsonResponse({'errno': 4103, 'errmsg': 'price格式有误'})
        if not int(room_count):
            return http.JsonResponse({'errno': 4103, 'errmsg': 'room_count格式有误'})
        if not int(acreage):
            return http.JsonResponse({'errno': 4103, 'errmsg': 'acreage格式有误'})
        if not int(capacity):
            return http.JsonResponse({'errno': 4103, 'errmsg': 'capacity格式有误'})
        if not int(deposit):
            return http.JsonResponse({'errno': 4103, 'errmsg': 'deposit格式有误'})
        if not int(min_days):
            return http.JsonResponse({'errno': 4103, 'errmsg': 'min_days格式有误'})
        if not int(max_days):
            return http.JsonResponse({'errno': 4103, 'errmsg': 'max_days格式有误'})

        # 保存房屋信息
        try:
            house = House.objects.create(
                user=request.user,
                area_id=area_id,
                title=title,
                price=price,
                address=address,
                room_count=room_count,
                acreage=acreage,
                unit=unit,
                capacity=capacity,
                beds=beds,
                deposit=deposit,
                min_days=min_days,
                max_days=max_days,

            )
        except Exception as e:
            print(e)
            return http.JsonResponse({'errno': 4001, 'errmsg': '数据库查询失败'})
        facilities = Facility.objects.filter(id__in=facilities)
        house.facilities.add(*facilities)
        # 新增房屋  响应给前端
        house_dict = {
            'id': house.id,
            'area_id': house.area_id,
            'title': house.title,
            'price': house.price,
            'address': house.address,
            'room_count': house.room_count,
            'acreage': house.acreage,
            'unit': house.unit,
            'capacity': house.capacity,
            'beds': house.beds,
            'deposit': house.deposit,
            'min_days': house.min_days,
            'max_days': house.max_days
        }
        return http.JsonResponse({'errno': 0, 'errmsg': 'ok', 'houses': house_dict})


# 首页房源推荐
class IndexListView(View):
    '''首页房源推荐'''

    def get(self, request):
        # 获取数据
        try:
            house = House.objects.all().order_by('order_count')
            print(house)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'errno': 4001, 'errmsg': 'DBERR'})

        # 定义房屋列表
        house_list = []
        # 整理数据
        for house_data in house:
            house_list.append({
                'house_id': house_data.id,
                'img_url': house_data.index_image_url,
                'title': house_data.title,
            })

        # 返回响应
        return http.JsonResponse({'data': house_list, 'errmsg': 'OK', 'errno': '0'})


# 首页房源搜索
class SearchView(View):
    '''首页搜索'''

    def get(self, request):

        json_dict = json.loads(request.body.decode())
        # 获取数据
        area_id = json_dict.get('aid')  # 区域id
        start_date = json_dict.get('sd')  # 开始时间
        end_date = json_dict.get('ed')  # 结束时间
        sk = json_dict.get('sk')  # 排序方式booking(订单量), price-inc(低到高), price-des(高到低)
        page = json_dict.get('p', '1')  # 页数，不传默认为1

        # 校验
        if not area_id:
            return http.JsonResponse({'errno': '4103', 'errmsg': 'PARAMERR'})
        if not start_date:
            return http.JsonResponse({'errno': '4103', 'errmsg': 'PARAMERR'})
        if not end_date:
            return http.JsonResponse({'errno': '4103', 'errmsg': 'PARAMERR'})
        if not sk:
            return http.JsonResponse({'errno': '4103', 'errmsg': 'PARAMERR'})

        # 判断开始时间是否大于结束时间
        new_start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d')
        new_end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d')
        # 如开始时间大于结束时间,则返回参数不对
        if new_start_date > new_end_date:
            return http.JsonResponse({'errno': '4103', 'errmsg': 'PARAMERR'})

        # 房屋过滤
        # 判断在哪个城区
        # house_filter = House.objects.filter(area=area_id)

        filters = {}
        if area_id:
            filters['area_id'] = area_id
        house_query = House.objects.filter(**filters)

        # 判断房屋是否被预定,过滤已预订的房屋
        conflict_order = None
        try:
            if start_date and end_date:
                conflict_order = Order.objects.filter(begin_date__lte=end_date, end_date__gte=start_date)
            elif start_date:
                conflict_order = Order.objects.filter(end_date__gte=start_date)
            elif end_date:
                conflict_order = Order.objects.filter(begin_date__lte=end_date)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'errno': 4001, 'errmsg': "DBERR"})

        if conflict_order:
            # 取到冲突订单的房屋id
            conflict_house_id = [order.house_id for order in conflict_order]
            house_query = house_query.exclude(id__in=conflict_house_id)

        # 根据筛选条件进行排序
        if sk == "booking":
            # 订单量排序
            house_filter = house_query.order_by('-order_count')
        elif sk == "price-inc":
            # 价格从低到高
            house_filter = house_query.order_by('price')
        elif sk == "price-des":
            # 价格从高到低
            house_filter = house_query.order_by('-price')
        else:
            # 创建时间排序
            house_filter = house_query.order_by('create_time')

        paginator = Paginator(house_filter, 5)
        # 获取每页商品数据
        try:
            page_houses = paginator.page(page)
        except EmptyPage:
            # 如果page_num不正确，默认给用户4103
            return http.JsonResponse({'code': 4103, 'errmsg': 'PARAMERR'})
        # 获取列表页总页数
        total_page = paginator.num_pages

        # 整理数据
        data_list = []
        for hf in page_houses:
            data_list.append({
                'house_id': hf.id,
                'order_count': hf.order_count,
                'title': hf.title,
                'ctime': hf.create_time.strftime("%Y-%m-%d"),
                "price": hf.price,
                "area_name": hf.area.name,
                "address": hf.address,
                "room_count": hf.room_count,
                "img_url": hf.index_image_url,
                "user_avatar": request.user.avatar_url if request.user.is_authenticated else "",
            })

        # 返回响应
        return http.JsonResponse({
            'errno': '0',
            'errmsg': 'OK',
            'data': {
                'houses': data_list,
                'total_page': total_page
            }
        })
